#ifndef WINDOW_H
#define WINDOW_H

#include <Windows.h>
#include <WindowsX.h>
#include <map>

class Window;

#include "resource.h"
#include "Utilities.h"


using namespace std;

class Window
{
public:
	typedef LRESULT (CALLBACK* WndProc)(LPVOID sender, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

	Window();
	virtual ~Window();

	virtual void Create(HINSTANCE hInstance, LPCTSTR className, WndProc wndProc = 0, DWORD exStyle = 0, DWORD style = WS_OVERLAPPEDWINDOW, UINT classStyle = 0, HBRUSH hbrBackground = 0, HCURSOR hCursor = 0, HICON hIcon = 0, HWND hWndParent = 0, HMENU hMenu = 0, LPVOID lpParam = 0);
	virtual void Close();

	HWND GetHWnd();

	virtual void Show();
	virtual void ShowNoActivate();
	virtual void Hide();
	virtual bool IsVisible();
	virtual bool IsTopMost();
	virtual void SetTopMost(bool value);
	virtual void SetScreenDocking(bool value);
	virtual bool GetScreenDocking();
	virtual void SetScreenDockingRange(int value);
	virtual int GetScreenDockingRange();
	virtual void SendToBottom();
	virtual void BringOnTop();
	virtual tstring GetText();
	virtual void SetText(tstring text);
	virtual void SetIcon(HICON hIcon);
	virtual HICON GetIcon();
	virtual void SetBackgroundBrush(HBRUSH hBrush);
	virtual HBRUSH GetBackgroundBrush();
	virtual void SetCursor(HCURSOR hCursor);
	virtual HCURSOR GetCursor();
	virtual RECT GetBounds();
	virtual void SetBounds(RECT value, bool force = false);
	virtual void SetBounds(LONG left, LONG top, LONG right, LONG bottom, bool force = false);
	virtual SIZE GetSize();
	virtual void SetSize(SIZE value, bool force = false);
	virtual void SetSize(LONG cx, LONG cy, bool force = false);
	virtual POINT GetLocation();
	virtual void SetLocation(POINT value);
	virtual void SetLocation(LONG x, LONG y);	
	virtual void Refresh();	
	virtual void SetTag(LPVOID tag);
	virtual LPVOID GetTag();

protected:
	HINSTANCE hInstance;
	WndProc wndProc;
	LPVOID tag;

	static map<HWND, Window*> instances;

private:
	HWND hWnd;
	bool screenDocking;
	int screenDockingRange;

	static Window* tmpInstance;
	
	static LRESULT CALLBACK BaseWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};

#endif
